package com.corpgovernment.permission.service;

import com.corpgovernment.common.base.ResourceInfo;
import com.corpgovernment.common.enums.ResourceEnum;
import com.corpgovernment.organization.entity.db.MbOrgInfo;
import com.corpgovernment.organization.mapper.MbOrgInfoMapper;
import com.corpgovernment.permission.entity.db.MbRoleResource;
import com.corpgovernment.redis.cache.RoleResourceManager;
import com.ctrip.corp.obt.generic.core.context.TenantContext;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ：xks
 * @date ：Created in 2022/7/20 10:40
 * @description：
 * @modified By：
 * @version: $
 */
@Slf4j
@Service
public class RoleResourceService {
    @Autowired
    private MbOrgInfoMapper orgInfoMapper;
    @Autowired
    private RoleResourceManager roleResourceManager;
    @Autowired
    private MbRoleResourceService mbRoleResourceService;
    @Autowired
    private MenuService menuService;

    /**
     * 角色资源  放进缓存
     *
     * @param roleId
     */
    public void setRoleResource(Long roleId) {
        ResourceInfo resourceData = getResourceData(roleId);
        roleResourceManager.setResource(String.valueOf(roleId), resourceData);
    }

    public void empty(Long roleId) {
        roleResourceManager.empty(String.valueOf(roleId));
    }

    public void addOneResource(Long roleId, Long resourceId, String orgId, String orgType, Integer type) {
        ResourceInfo resourceData = this.getResourceData(roleId);
        if (Objects.equals(ResourceEnum.DEPT.getCode(), type)) {
            resourceData.getDeptInfos().add(
                    ResourceInfo.DeptInfo.builder().orgId(orgId)
                            .id(resourceId)
                            .orgType(orgType).build()
            );
        } else {
            //暂不支持通过接口添加菜单
        }

        roleResourceManager.setResource(String.valueOf(roleId), resourceData);
        log.info("addOneResource更新redis缓存,roleId:{},resourceData:{}",roleId, JsonUtils.toJsonString(resourceData));
    }


    public ResourceInfo getResourceData(Long roleId) {

        ResourceInfo resourceInfo = new ResourceInfo();

        List<MbRoleResource> resourceData = mbRoleResourceService.findByRoleId(roleId);

        //部门
        List<MbRoleResource> dept = resourceData.stream().filter(a -> Objects.equals(ResourceEnum.DEPT.getCode(), a.getType())).collect(Collectors.toList());
        Example example = new Example(MbOrgInfo.class);
        example.createCriteria().andIn("id", dept.stream().map(MbRoleResource::getResourceId).collect(Collectors.toList())).andEqualTo("deleteTime", new Date(0)).andEqualTo("isBackground", 0);
        if (CollectionUtils.isNotEmpty(dept)) {
            resourceInfo.setDeptInfos(
                    Optional.ofNullable(orgInfoMapper.selectByExample(example)).orElse(new ArrayList<>()).stream().map(d -> ResourceInfo.DeptInfo.builder().id(d.getId()).orgId(d.getOrgId()).orgType(d.getOrgType()).parentId(d.getParentId()).build()).collect(Collectors.toList())
            );
        }
        //菜单
        List<MbRoleResource> perm = resourceData.stream().filter(a -> Objects.equals(ResourceEnum.PERMISSION.getCode(), a.getType())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(perm)) {
            resourceInfo.setPermissionInfos(
                    TenantContext.ignoreTenantContext(()->
                    menuService.getMenuByIds(perm.stream().map(MbRoleResource::getResourceId).collect(Collectors.toList())).stream().map(p -> ResourceInfo.PermissionInfo.builder().id(p.getId()).key(p.getKey()).path(p.getUrl()).build()).collect(Collectors.toList())
                    ));
        }

        // 开票
        List<MbRoleResource> invoceResourceList = resourceData.stream().filter(a -> Objects.equals(ResourceEnum.INVOICING.getCode(), a.getType())).collect(Collectors.toList());
        Example mbOrgInfoExample = new Example(MbOrgInfo.class);
        mbOrgInfoExample.createCriteria().andIn("id", invoceResourceList.stream().map(MbRoleResource::getResourceId).collect(Collectors.toList())).andEqualTo("deleteTime", new Date(0)).andEqualTo("isBackground", 0);
        if (CollectionUtils.isNotEmpty(invoceResourceList)) {
            resourceInfo.setInvoiceInfos(
                    Optional.ofNullable(orgInfoMapper.selectByExample(mbOrgInfoExample)).orElse(new ArrayList<>()).stream().map(d -> ResourceInfo.DeptInfo.builder().id(d.getId()).orgId(d.getOrgId()).orgType(d.getOrgType()).parentId(d.getParentId()).build()).collect(Collectors.toList())
            );
        }

        return resourceInfo;
    }

    public void delOneRoleResourceData(Long roleId, Long delId, Integer type) {
        ResourceInfo resourceData = this.getResourceData(roleId);
        if (Objects.equals(ResourceEnum.DEPT.getCode(), type)) {
            resourceData.setDeptInfos(Optional.ofNullable(resourceData.getDeptInfos()).orElse(new ArrayList<>()).stream().filter(a -> !Objects.equals(delId, a.getId())).collect(Collectors.toList()));
        } else {
            resourceData.setPermissionInfos(Optional.ofNullable(resourceData.getPermissionInfos()).orElse(new ArrayList<>()).stream().filter(a -> !Objects.equals(delId, a.getId())).collect(Collectors.toList()));
        }
        roleResourceManager.setResource(String.valueOf(roleId), resourceData);
    }
}
